package ElasticSearch

import (
	"context"
	"github.com/olivere/elastic/v7"
	"strings"
	"sync"
)


var (
	mapClient = sync.Map{}
	lock sync.Mutex // 连接锁定防止并发访问
)

//ElasticClient 客户端
type ElasticClient struct {
	client *elastic.Client
	index  string
}

//GetElasticClient 获取es客户端对象
func GetElasticClient(config map[string]string) (*ElasticClient, error) {
	keyConn := config["ipport"]
	client, ok := mapClient.Load(keyConn)
	if ok {
		return client.(*ElasticClient), nil
	}

	lock.Lock()
	defer lock.Unlock()

	/*二次获取防止并发多次连接*/
	client, ok = mapClient.Load(keyConn)
	if ok {
		return client.(*ElasticClient), nil
	}

	newClient, err := connect(config)
	if err != nil {
		return nil, err
	}
	elasticClient := &ElasticClient{
		client: newClient,
		index:  strings.ToLower(config["dbname"]),
	}
	mapClient.Store(keyConn, elasticClient)
	return elasticClient, nil
}

//connect 获取客户端
func connect(config map[string]string) (*elastic.Client, error) {
	host, ok := config["ipport"]
	if !ok {
		host = "http://127.0.0.1:9200"
	}
	hostAry := strings.Split(host,",")

	username,ok := config["username"]
	if !ok{
		username = ""
	}
	password,ok := config["password"]
	if !ok {
		password = ""
	}

	//这个地方有个小坑 不加上elastic.SetSniff(false) 会连接不上
	client, err := elastic.NewClient(
		elastic.SetSniff(false),
		elastic.SetURL(hostAry...),
		elastic.SetBasicAuth(username,password))

	if err != nil {
		return nil, err
	}
	_,_,err = client.Ping(host).Do(context.Background())
	if err != nil {
		return nil, err
	}
	//fmt.Printf("Elasticsearch returned with code %d and version %s\n", code, info.Version.Number)
	_,err = client.ElasticsearchVersion(host)
	if err != nil {
		return nil, err
	}
	return client,nil
}